package recite.word.client.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;
import recite.word.client.dto.search.SearchAddOne;
import recite.word.client.dto.search.SearchListDTO;
import recite.word.client.service.ISearchService;
import recite.word.client.vo.search.SearchListVO;
import recite.word.mybatis.auto.dao.SearchRecordMapper;
import recite.word.mybatis.auto.dao.UserWordMapper;
import recite.word.mybatis.auto.model.SearchRecord;
import recite.word.mybatis.auto.model.UserWord;
import recite.word.service.base.common.enums.DeleteEnum;
import recite.word.service.base.common.request.BaseRequest;
import recite.word.service.base.common.threadLocal.UserContent;
import recite.word.service.base.util.common.Asserts;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class SearchServiceImpl implements ISearchService {
    @Resource
    private UserWordMapper userWordMapper;
    @Resource
    private SearchRecordMapper searchRecordMapper;

    /**
     * 模糊搜索单词
     * @param dto
     * @return
     */
    @Override
    public List<SearchListVO> getSearchList(BaseRequest<SearchListDTO> dto) {
        // 根据用户单词表去搜索, 用唯一单词表的话会找不到用户是否收藏, 但是这样用户只能查到自己有的单词书的单词了
        SearchListDTO data = dto.getData();
        // 传递单词前缀为空时返回空
        if (StrUtil.isBlank(data.getPreWord())) return null;
        List<UserWord> userWords = userWordMapper.selectList(new LambdaQueryWrapper<UserWord>()
                .eq(UserWord::getUserId, UserContent.get())
                .eq(UserWord::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode())
                .likeRight(UserWord::getWord, data.getPreWord())
                .orderByDesc(UserWord::getCreatedTime));
        List<SearchListVO> ans = new ArrayList<>();
        for (UserWord userWord : userWords) {
            SearchListVO vo = new SearchListVO();
            vo.setMeanCn(userWord.getMeanCn());
            vo.setWord(userWord.getWord());
            vo.setAccent(userWord.getAccent());
            vo.setId(userWord.getId());
            ans.add(vo);
        }
        return ans;
    }

    /**
     * 查询历史记录(默认前8条)
     * @return
     */
    @Override
    public List<SearchListVO> getHistory() {
        Long userId = UserContent.get();
        // 根据编辑时间来排序
        List<SearchRecord> searchRecords = searchRecordMapper.selectList(new LambdaQueryWrapper<SearchRecord>()
                .eq(SearchRecord::getUserId, userId)
                .eq(SearchRecord::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode())
                .orderByDesc(SearchRecord::getEditTime)
                .last("limit 8"));
        List<SearchListVO> ans = new ArrayList<>();
        for (SearchRecord searchRecord : searchRecords) {
            UserWord word = userWordMapper.selectById(searchRecord.getUserWordId());
            SearchListVO vo = new SearchListVO();
            vo.setId(word.getId());
            vo.setWord(word.getWord());
            vo.setMeanCn(word.getMeanCn());
            vo.setAccent(word.getAccent());
            ans.add(vo);
        }
        return ans;
    }

    /**
     * 点击具体搜索单词
     * @param dto
     */
    @Override
    public void addOne(BaseRequest<SearchAddOne> dto) {
        SearchAddOne data = dto.getData();
        Asserts.isTrue(ObjectUtil.isNotNull(data.getId()),"用户单词id为空");
        Long userId = UserContent.get();
        // 已经在搜索记录中的单词只用修改编辑时间
        SearchRecord one = searchRecordMapper.selectOne(new LambdaQueryWrapper<SearchRecord>()
                .eq(SearchRecord::getUserId, userId)
                .eq(SearchRecord::getUserWordId, data.getId())
                .eq(SearchRecord::getDeleteStatus, DeleteEnum.NOT_DELETED.getCode()));
        if (ObjectUtil.isNotNull(one)) {
            one.setEditTime(LocalDateTime.now());
            int b = searchRecordMapper.updateById(one);
            Asserts.isTrue(b == 1, "修改编辑状态失败");
            return;
        }
        // 还没有的添加到记录表中
        SearchRecord searchRecord = new SearchRecord();
        searchRecord.setUserId(userId);
        searchRecord.setUserWordId(data.getId());
        int b = searchRecordMapper.insert(searchRecord);
        Asserts.isTrue(b == 1, "添加历史记录失败");
    }

    /**
     * 清空历史
     */
    @Override
    public void cleanHistory() {
        Long userId = UserContent.get();
        int update = searchRecordMapper.update(null, new LambdaUpdateWrapper<SearchRecord>()
                .eq(SearchRecord::getUserId, userId)
                .set(SearchRecord::getDeleteStatus, DeleteEnum.DELETED.getCode()));
    }
}
